<template>
  <div
    :class="[
      'stat-card',
      `stat-card--${variant}`,
      `stat-card--${size}`,
      { 'stat-card--interactive': interactive },
      { 'stat-card--loading': loading }
    ]"
    @click="handleClick"
  >
    <!-- 加载状态 -->
    <div v-if="loading" class="stat-card__loading">
      <div class="loading-skeleton">
        <div class="skeleton-icon"></div>
        <div class="skeleton-content">
          <div class="skeleton-number"></div>
          <div class="skeleton-label"></div>
        </div>
      </div>
    </div>

    <!-- 正常状态 -->
    <div v-else class="stat-card__content">
      <!-- 图标区域 -->
      <div v-if="icon || $slots.icon" class="stat-card__icon">
        <slot name="icon">
          <div :class="['icon-wrapper', `icon-wrapper--${iconType}`]">
            <component :is="icon" />
          </div>
        </slot>
      </div>

      <!-- 数值区域 -->
      <div class="stat-card__data">
        <div class="stat-number">
          <span v-if="prefix" class="number-prefix">{{ prefix }}</span>
          <span class="number-value">{{ formattedValue }}</span>
          <span v-if="suffix" class="number-suffix">{{ suffix }}</span>
        </div>

        <div class="stat-label">{{ label }}</div>

        <!-- 趋势指示器 -->
        <div v-if="trend !== undefined" class="stat-trend">
          <div :class="['trend-indicator', `trend-indicator--${trendDirection}`]">
            <tiny-icon-arrow-up v-if="trendDirection === 'up'" />
            <tiny-icon-arrow-down v-if="trendDirection === 'down'" />
            <tiny-icon-minus v-if="trendDirection === 'neutral'" />
            <span class="trend-value">{{ Math.abs(trend) }}%</span>
          </div>
          <span v-if="trendLabel" class="trend-label">{{ trendLabel }}</span>
        </div>
      </div>

      <!-- 额外操作 -->
      <div v-if="$slots.action" class="stat-card__action">
        <slot name="action" />
      </div>
    </div>

    <!-- 卡片底部 -->
    <div v-if="$slots.footer || description" class="stat-card__footer">
      <slot name="footer">
        <p v-if="description" class="stat-description">{{ description }}</p>
      </slot>
    </div>

    <!-- 悬浮工具提示 -->
    <div v-if="tooltip" class="stat-card__tooltip">
      {{ tooltip }}
    </div>
  </div>
</template>

<script lang="ts" setup>
import {computed} from 'vue'

// Props
interface Props {
  value: number | string
  label: string
  icon?: string
  iconType?: 'primary' | 'success' | 'warning' | 'error' | 'info' | 'default'
  variant?: 'default' | 'bordered' | 'gradient' | 'minimal'
  size?: 'small' | 'medium' | 'large'
  prefix?: string
  suffix?: string
  description?: string
  tooltip?: string
  trend?: number
  trendLabel?: string
  loading?: boolean
  interactive?: boolean
  formatType?: 'number' | 'percentage' | 'currency' | 'bytes'
  precision?: number
}

const props = withDefaults(defineProps<Props>(), {
  iconType: 'default',
  variant: 'default',
  size: 'medium',
  loading: false,
  interactive: false,
  formatType: 'number',
  precision: 0
})

// Emits
const emit = defineEmits<{
  'click': [event: Event]
}>()

// 计算属性
const formattedValue = computed(() => {
  if (typeof props.value === 'string') return props.value

  const num = Number(props.value)

  switch (props.formatType) {
    case 'percentage':
      return (num * 100).toFixed(props.precision) + '%'
    case 'currency':
      return '¥' + num.toLocaleString('zh-CN', {
        minimumFractionDigits: props.precision,
        maximumFractionDigits: props.precision
      })
    case 'bytes':
      return formatBytes(num)
    case 'number':
    default:
      if (num >= 1000000) {
        return (num / 1000000).toFixed(1) + 'M'
      } else if (num >= 1000) {
        return (num / 1000).toFixed(1) + 'K'
      }
      return num.toLocaleString('zh-CN', {
        minimumFractionDigits: props.precision,
        maximumFractionDigits: props.precision
      })
  }
})

const trendDirection = computed(() => {
  if (props.trend === undefined || props.trend === 0) return 'neutral'
  return props.trend > 0 ? 'up' : 'down'
})

// 工具函数
const formatBytes = (bytes: number): string => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]
}

// 事件处理
const handleClick = (event: Event) => {
  if (props.interactive) {
    emit('click', event)
  }
}
</script>

<style lang="scss" scoped>
.stat-card {
  position: relative;
  background: white;
  border-radius: $radius-lg;
  transition: all $duration-normal $ease-out-quart;
  overflow: hidden;

  &--small {
    padding: $spacing-4;

    .stat-card__icon .icon-wrapper {
      width: 40px;
      height: 40px;
      font-size: 20px;
    }

    .stat-number {
      font-size: $text-lg;
    }

    .stat-label {
      font-size: $text-xs;
    }
  }

  &--medium {
    padding: $spacing-6;

    .stat-card__icon .icon-wrapper {
      width: 48px;
      height: 48px;
      font-size: 24px;
    }

    .stat-number {
      font-size: $text-2xl;
    }

    .stat-label {
      font-size: $text-sm;
    }
  }

  &--large {
    padding: $spacing-8;

    .stat-card__icon .icon-wrapper {
      width: 56px;
      height: 56px;
      font-size: 28px;
    }

    .stat-number {
      font-size: $text-3xl;
    }

    .stat-label {
      font-size: $text-base;
    }
  }

  &--default {
    border: 1px solid $gray-200;
  }

  &--bordered {
    border: 2px solid $gray-200;
  }

  &--gradient {
    background: $gradient-subtle;
    border: 1px solid rgba(255, 255, 255, 0.5);
  }

  &--minimal {
    background: transparent;
    border: none;
  }

  &--interactive {
    cursor: pointer;

    &:hover {
      transform: translateY(-2px);
      box-shadow: $shadow-lg;

      &.stat-card--bordered {
        border-color: $primary-300;
      }
    }
  }

  &--loading {
    pointer-events: none;
  }

  .stat-card__loading {
    .loading-skeleton {
      display: flex;
      align-items: center;
      gap: $spacing-4;

      .skeleton-icon {
        width: 48px;
        height: 48px;
        border-radius: $radius-lg;
        background: $gray-200;
        animation: skeleton-pulse 1.5s ease-in-out infinite;
      }

      .skeleton-content {
        flex: 1;

        .skeleton-number {
          height: 24px;
          width: 80px;
          background: $gray-200;
          border-radius: $radius-sm;
          margin-bottom: $spacing-2;
          animation: skeleton-pulse 1.5s ease-in-out infinite;
        }

        .skeleton-label {
          height: 16px;
          width: 60px;
          background: $gray-200;
          border-radius: $radius-sm;
          animation: skeleton-pulse 1.5s ease-in-out infinite;
        }
      }
    }
  }

  .stat-card__content {
    display: flex;
    align-items: flex-start;
    gap: $spacing-4;
    position: relative;

    .stat-card__icon {
      .icon-wrapper {
        display: flex;
        align-items: center;
        justify-content: center;
        border-radius: $radius-lg;
        flex-shrink: 0;

        &--primary {
          background: rgba($primary-500, 0.1);
          color: $primary-600;
        }

        &--success {
          background: rgba($success-500, 0.1);
          color: $success-600;
        }

        &--warning {
          background: rgba($warning-500, 0.1);
          color: $warning-600;
        }

        &--error {
          background: rgba($error-500, 0.1);
          color: $error-600;
        }

        &--info {
          background: rgba($info-500, 0.1);
          color: $info-600;
        }

        &--default {
          background: rgba($gray-500, 0.1);
          color: $gray-600;
        }
      }
    }

    .stat-card__data {
      flex: 1;
      min-width: 0;

      .stat-number {
        font-weight: $font-bold;
        color: $gray-800;
        line-height: $leading-none;
        margin-bottom: $spacing-1;
        display: flex;
        align-items: baseline;

        .number-prefix,
        .number-suffix {
          font-size: 0.7em;
          color: $gray-600;
          font-weight: $font-medium;
        }

        .number-prefix {
          margin-right: $spacing-1;
        }

        .number-suffix {
          margin-left: $spacing-1;
        }
      }

      .stat-label {
        color: $gray-600;
        font-weight: $font-medium;
        margin-bottom: $spacing-2;
      }

      .stat-trend {
        display: flex;
        align-items: center;
        gap: $spacing-2;

        .trend-indicator {
          display: flex;
          align-items: center;
          gap: 2px;
          font-size: $text-xs;
          font-weight: $font-medium;

          &--up {
            color: $success-600;
          }

          &--down {
            color: $error-600;
          }

          &--neutral {
            color: $gray-500;
          }
        }

        .trend-label {
          font-size: $text-xs;
          color: $gray-500;
        }
      }
    }

    .stat-card__action {
      flex-shrink: 0;
    }
  }

  .stat-card__footer {
    margin-top: $spacing-4;
    padding-top: $spacing-4;
    border-top: 1px solid $gray-100;

    .stat-description {
      font-size: $text-sm;
      color: $gray-500;
      margin: 0;
      line-height: $leading-relaxed;
    }
  }

  .stat-card__tooltip {
    position: absolute;
    top: -10px;
    right: -10px;
    background: $gray-800;
    color: white;
    padding: $spacing-2 $spacing-3;
    border-radius: $radius-md;
    font-size: $text-xs;
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transform: translateY(-100%);
    transition: all $duration-normal ease;
    z-index: 10;

    &::after {
      content: '';
      position: absolute;
      top: 100%;
      left: 50%;
      transform: translateX(-50%);
      border: 4px solid transparent;
      border-top-color: $gray-800;
    }
  }

  &:hover .stat-card__tooltip {
    opacity: 1;
    transform: translateY(-100%) translateY(-8px);
  }
}

// 动画定义
@keyframes skeleton-pulse {
  0%, 100% {
    background-color: $gray-200;
  }
  50% {
    background-color: $gray-300;
  }
}

// 暗色主题
[data-theme="dark"] {
  .stat-card {
    background: $dark-100;

    &--default,
    &--bordered {
      border-color: $dark-200;
    }

    &--gradient {
      background: linear-gradient(135deg, $dark-100 0%, $dark-200 100%);
    }

    .stat-card__loading {
      .loading-skeleton {
        .skeleton-icon,
        .skeleton-number,
        .skeleton-label {
          background: $dark-200;
        }
      }
    }

    .stat-card__content {
      .stat-card__data {
        .stat-number {
          color: $dark-800;

          .number-prefix,
          .number-suffix {
            color: $dark-600;
          }
        }

        .stat-label {
          color: $dark-600;
        }

        .stat-trend .trend-label {
          color: $dark-500;
        }
      }
    }

    .stat-card__footer {
      border-top-color: $dark-200;

      .stat-description {
        color: $dark-600;
      }
    }

    .stat-card__tooltip {
      background: $dark-800;

      &::after {
        border-top-color: $dark-800;
      }
    }
  }
}
</style>
